package mbsl.books;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Shell;

import mbsl.commons.Commons;
import mbsl.commons.base.CommentPanel;
import mbsl.commons.lib.Comment;
import mbsl.system.TextProvider;
import mbsl.ui.Tree;
import mbsl.ui.Tree.TreeNode;
import mbsl.ui.dialogs.Dialogs;
import mbsl.ui.interfaces.Listener;

public class BookViewController {
	private static TextProvider tp = Commons.tp.prefix("common.comments");

	public BookViewController(BookController pParent, Shell pWindow) {
		mDialog = new BookViewDialog(pWindow);
		mParent = pParent;
		
		mCommentPanel = mDialog.getCommentPanel();
		
		mCommentPanel.addSaveListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent pE) {
				if (mCommentPanel.getActiveComment().getTitle().trim().isEmpty()) {
					Dialogs.error(mDialog.getWindow(), tp.get("fillMessage"), tp.get("titleError"));
					return;
				}
				if (mCommentPanel.getActiveComment().getBody().trim().isEmpty()) {
					Dialogs.error(mDialog.getWindow(), tp.get("fillMessage"), tp.get("bodyError"));
					return;
				}
				
				if (mElement.getComments() == null)
					mElement.setComments(new ArrayList<Comment<Book>>());

				boolean isNew;
				Comment<Book> comment;

				if (mCommentPanel.isNewActive()) {
					mElement.getComments().add(new Comment<Book>());
					
					comment = mElement.getComments().get(mElement.getComments().size() - 1);
					isNew = true;
				} else {
					// The comments are added in reverse order
					comment = mElement.getComments().get(mElement.getComments().size() - 1 - mCommentPanel.getActiveCommentIndex());
					isNew = false;
				}

				comment.setBody(mCommentPanel.getActiveComment().getBody());
				comment.setName(mCommentPanel.getActiveComment().getTitle());
				
				mParent.getCore().getDatabase().save(mElement);
				
				if (isNew) {
					mCommentPanel.getActiveComment().setBody(null);
					mCommentPanel.getActiveComment().setTitle(null);
					
					addComment(comment);
				}
			}
		});
		mCommentPanel.addDeleteListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent pE) {
				Comment<Book> comment = mElement.getComments().get(mElement.getComments().size() - 1 - mCommentPanel.getActiveCommentIndex());
				
				mElement.getComments().remove(comment);
				
				mParent.getCore().getDatabase().delete(comment);
				mParent.getCore().getDatabase().save(mElement);
				
				mCommentPanel.removeComment(mCommentPanel.getActiveCommentIndex());
			}
		});
		mDialog.getRating().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent pE) {
				mElement.setRating(mDialog.getRating().getValue());
				
				mParent.getCore().getDatabase().save(mElement);
				
				if (mListeners != null)
					for (Listener listener : mListeners)
						listener.alert();
			}
		});
	}

	public void setElement(Book pElement) {
		if (pElement == mElement)
			return;
		
		mElement = pElement;
		
		mDialog.setTitle(mElement.getName());
		
		if (mElement.getGenre() != null)
			mDialog.setGenre(mElement.getGenre().getName());
		if (mElement.getLocation() != null)
			mDialog.setLocation(mElement.getLocation().getName());
		if (mElement.getRating() >= 0)
			mDialog.setRating(mElement.getRating());
		else
			mDialog.setRating(0);
		mDialog.setYear(mElement.getYear());
		if (mElement.getFormat() != null)
			mDialog.setFormat(mElement.getFormat().getName());
		if (mElement.getAuthor() != null)
			if (mElement.getAuthor().getFirstName() != null)
				mDialog.setAuthor(mElement.getAuthor().getFirstName() + " " + mElement.getAuthor().getSurname());
			else
				mDialog.setAuthor(mElement.getAuthor().getSurname());
		
		mCommentPanel.clear();
		
		if (mElement.getComments() != null)
			for (Comment<Book> comment : mElement.getComments())
				addComment(comment);
		
		Tree tree = mDialog.getTree();
		
		tree.clear();
		
		if (mElement.getParent() != null || !mElement.getChildren().isEmpty())
			buildTree(tree);
	}
	private void buildTree(Tree pTree) {
		Book root = mElement;
		
		// Let's find the root of this tree
		while (root.getParent() != null)
			root = root.getParent();
		
		TreeNode node = pTree.new TreeNode();
		
		node.setData(root);
	
		buildSubTree(pTree, node);
	}
	private void buildSubTree(Tree pTree, TreeNode pNode) {
		// Effectively a DFS for building the set of TreeNodes.
		for (Book child : ((Book)pNode.getData()).getChildren()) {
			TreeNode childNode = pTree.new TreeNode(pNode);
			
			childNode.setData(child);
			
			buildSubTree(pTree, childNode);
		}
	}
	public Book getElement() {
		return mElement;
	}
	private void addComment(Comment<Book> pComment) {
		mCommentPanel.addComment(pComment.getName(), String.format("%1$tY-%1$tm-%1$td", pComment.getPosted()), pComment.getBody());
	}
	public void open() {
		mDialog.open();
	}
	public void addChangeListener(Listener pListener) {
		if (mListeners == null)
			mListeners = new ArrayList<Listener>();
		
		mListeners.add(pListener);
	}

//	private static Preferences prefs = Core.getPreferences().node("books");
	
	private List<Listener> mListeners;
	private Book mElement;
	private CommentPanel mCommentPanel;
	private BookViewDialog mDialog;
	private BookController mParent;
}
